package edu.xidian.sei

import java.io.File

import scala.io.Source
import scala.sys.ShutdownHookThread
import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.Props
import edu.xidian.sei.stream.GridMap
import edu.xidian.sei.util.Stopwatch
import java.util.concurrent.TimeUnit
import java.util.Date
import java.text.SimpleDateFormat

import com.typesafe.config.ConfigFactory
import edu.xidian.sei.local.LocalReactor

/**
  * @author zhi
  *         cup99
  */
object LocalClient {

  val sdf = new SimpleDateFormat("yyyy.MM.dd-HH:mm:ss.SSS")

  def main(args: Array[String]): Unit = {
    val config = ConfigFactory.parseFile(new File("analyzer.conf")).getConfig("master")
    val start = System.nanoTime()
    //    val dir = new File(args(0)).getParent
    val dir = new File(config.getString(EDStreamConfig.InputFileName)).getParent
    val output = dir + (if (dir.endsWith(File.separator)) "output" else "/output")

    //初始化算法参数
    val prompts = new StringBuilder

    //数据流空间维数 int
    val dimension = config.getInt(EDStreamConfig.GridDimensionName)
    prompts.append(" Dimension=" + dimension)

    //网格所划分的长度 double
    val length = config.getDouble(EDStreamConfig.GridLengthName)
    prompts.append(" Length=" + length)

    //数据流空间中每维的数据范围 double
    val upbound = config.getDouble(EDStreamConfig.GridUpboundName)
    prompts.append(" Upbound=" + upbound)

    //是否访问网格的全部邻居 boolean
    Space.isComplete = config.getBoolean(EDStreamConfig.GridIsCompleteName)
    prompts.append(" IsComplete=" + Space.isComplete)

    //本地模式下子分析器数量 int
    val threadNum = config.getInt(EDStreamConfig.LocalActorCountName)
    prompts.append(" ThreadNum=" + threadNum)

    //切片数量 int
    val aliceNum = config.getInt(EDStreamConfig.SliceCountName)
    prompts.append(" AliceNum=" + aliceNum)

    //数据流的流速 int
    val streamRate = config.getInt(EDStreamConfig.StreamRateName)
    prompts.append(" StreamRate=" + aliceNum)
    println(prompts.toString)

    val gridMap = GridMap(Space(dimension, length, upbound), new LocalReactor(output))
    val system = ActorSystem.apply("LocalClient")
    val gridManager = system.actorOf(Props(classOf[GridManager], gridMap, system))
    val filereader = Source.fromFile(args(0)).getLines().toList
    val dataBlock = filereader.sliding(streamRate, streamRate).toList
    val startTime = System.nanoTime()
    var datanum = 0
    dataBlock.foreach(block => {
      datanum += 1
      gridManager ! block
      println("数据" + datanum + "发送完毕:" + sdf.format(new Date))
      TimeUnit.SECONDS.sleep(1)
    })

    gridManager ! "finish"

    ShutdownHookThread {
      println(Stopwatch.format(System.nanoTime() - startTime))
    }
  }

}

class GridManager(gridMap: GridMap, system: ActorSystem) extends Actor {

  def receive = {
    case block: List[_] => {
      for (line <- block) {
        val str = line.asInstanceOf[String]
        gridMap.touch(Location.of(str.split("[;|,|\\s]")))
      }
    }
    case "finish" =>
      println("finish")
      gridMap.cleanup()
      context.stop(self)
      system.terminate()
  }
}